
import { SubjectComponent } from '../prefab/subject_component';
import MsgHub from './msg_hub';
import utils from './utils';
const { ccclass, property } = cc._decorator;

@ccclass("SoundHandle")
class SoundHandle {
    @property( cc.String )
    name = "";
    @property(cc.AudioClip)
    public clip: cc.AudioClip | null = null;
};


@ccclass
export class SoundMgr extends SubjectComponent {
    protected _playingList: Map<string, cc.AudioClip> = new Map();
 
    @property( cc.Boolean )
    muted = false;
    @property([SoundHandle])
    lib: SoundHandle[] = [];

    onLoad() {
        MsgHub.on("sound_mgr", this.onGetThis, this);
        MsgHub.on("play_clip", this.playClip, this);
        MsgHub.on("stop_clip", this.stopClip, this );
        utils.soundMgr = this;
    }

    onGetThis(msg: any) {
        msg.handle = this;
    }

    playClip(msg: any) {
        if (this.muted) {
            return;
        }

        let _msg = {
            name: "",
            loop: false,
            volDetail: 1.0,
            fadeTime: 0,
            override: true,
        };
        if (typeof msg === "string") {
            _msg.name = msg;
        }
        else {
            Object.assign(_msg, msg);
        }
        msg = _msg;

        let oldClip = this._playingList.get(msg.name);
        if (!msg.override && oldClip) {
            return;
        }

        if (msg.override && oldClip) {
            this._playingList.delete(msg.name);
            oldClip.stop();
        }

        let clip = this.getClip(msg.name);
        if (!clip) {
            cc.log(`没有找到Clip`);
            return;
        }
        this._playingList.set(msg.name, clip);
        new Promise<void>((resolve, reject) => {
            clip?.setVolume(msg.volDetail);
            clip?.play();
            // clip?.on("started", () => {
            // }, this);
            clip?.once("ended", () => {
                resolve();
            });
        }).then(() => {
            this._playingList.delete(msg.name);
            if( msg.loop ) {
                this.playClip( msg );
            }
        });
    }

    stopClip( msg : any ) {
        let _msg = {
            name: "",
            fadeTime: 0,
        };
        if (typeof msg === "string") {
            _msg.name = msg;
        }
        else {
            Object.assign(_msg, msg);
        }
        msg = _msg;
        let oldClip = this._playingList.get(msg.name);
        if( !oldClip ) {
            return;
        }

        this._playingList.delete(msg.name);
        oldClip.stop();
    }

    getClip(name: string) {
        for (let i = 0; i < this.lib.length; i++) {
            let sh = this.lib[i];
            if (sh.name === name) {
                return sh.clip;
            }
        }
        return null;
    }
    lateUpdate() {
        let context = sys.__audioSupport.context;
        window.AST = context.state;
        // "suspended", "running"
        if (context.state === 'suspended') {
            context.resume();
        }
    }
};